import EditorJS from "@editorjs/editorjs"
import katex from "katex"

export default class InlineMathTool implements EditorJS.InlineTool {
	private api: EditorJS.API
	static get isInline() {
		return true
	}

	constructor({ api }: { api: EditorJS.API }) {
		this.api = api
	}

	render() {
		const button = document.createElement("button")
		button.type = "button"
		button.textContent = "f(x)"
		button.classList.add("ce-inline-tool", "ce-inline-math-tool")
		return button
	}

	surround(range: Range) {
		if (!range) return

		const container = range.commonAncestorContainer
		const element = container.nodeType === Node.TEXT_NODE ? container.parentElement : (container as Element)

		// 如果当前选中文本的父元素是数学公式, 则返回
		if (!element?.classList.contains("ce-paragraph") && (element?.classList.contains("mord") || element?.querySelector(".inline-math"))) {
			return
		}

		let selectedText = range.extractContents().textContent || ""
		const mathSpan = document.createElement("span")
		mathSpan.classList.add("inline-math")
		// 兼容公式$符号,  如果是$符号, 则去掉$符号
		if (selectedText.startsWith("$") && selectedText.endsWith("$")) {
			selectedText = selectedText.slice(1, -1)
		}
		mathSpan.dataset.tex = selectedText
		this.renderMath(mathSpan, selectedText)
		range.insertNode(mathSpan)
		this.api.inlineToolbar.close()
		setTimeout(() => {
			// 取消选中状态
			const selection = window.getSelection()
			if (element?.contains(range.commonAncestorContainer)) {
				if (selection?.removeRange) {
					selection.removeRange(range)
				} else if (selection?.removeAllRanges) {
					selection.removeAllRanges()
				}
			}
		}, 600)
	}

	checkState() {
		const selection = this.api.selection
		const parentElement = selection.findParentTag("SPAN")
		return parentElement && parentElement.classList.contains("inline-math")
	}

	renderMath(element: HTMLElement, tex: string) {
		try {
			katex.render(tex, element, {
				throwOnError: false,
				displayMode: false,
			})
		} catch (error) {
			console.error("KaTeX rendering error:", error)
			element.textContent = tex
		}
	}

	static get sanitize() {
		return {
			span: {
				class: "inline-math",
				"data-tex": true,
			},
		}
	}
}

